package com.laoyao.beans;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;

import org.junit.Test;

import com.laoyao.util.DateUtil;
import com.laoyao.util.abc;

public class Aho {
	private String[] keywords;
	private TrieNode root;
	
	Aho(String[] keywords){
		this.keywords =keywords;
		root = build(keywords);
		//printTrie(root);
		buildFail(root);
	}
	
	public TrieNode build(String[] keywords ){
		TrieNode root = new TrieNode('\0');
		
		for(String word : keywords){
			TrieNode temp = root;
			char[] chs =  word.toCharArray();
			//判断子节点是否包含改字符如果包含则指向该节点，不包含则创建新的子节点并指向该节点
			for(Character ch : chs){
				if(!temp.getChildren().containsKey(ch)){
					TrieNode node = new TrieNode(ch);
					temp.getChildren().put(ch, node);
					temp=node;
				}else{
					temp=temp.getChildren().get(ch);
				}
			}
			temp.setLength(word.length());		
		}
		
		return root;
	}
	
	//建立fail指针
	public void buildFail(TrieNode root){
		Queue<TrieNode> q = new LinkedList<TrieNode>();
		
		root.setFail(null);
		
		q.offer(root);	
		while(!q.isEmpty()){
			TrieNode item = q.poll();
			Collection<TrieNode> children = item.getChildren().values();
			for(TrieNode child : children){
				if(item==root){
					child.setFail(root);
				}else{
					
					TrieNode fail = item.getFail();
					while(fail!=null){
						
						if(fail.getChildren().containsKey(child.getValue())){
							child.setFail(fail.getChildren().get(child.getValue()));
							break;
						}
						fail=fail.getFail();
					}
					if(fail==null)  child.setFail(root);
				}
				q.offer(child);
			}		
		}		
		
	}
	
	public String replaceKey(String str,Integer start,Integer end){
		
		StringBuffer sb = new StringBuffer(str);
		
		sb.replace(start, end, "*");
	
		return sb.toString();
	}
	
	public String wordPass(String str){
		char[] chs = str.toCharArray();
		int len = chs.length;
		TrieNode temp = this.root;
		for(int i=0;i<len;i++){
					
			while(temp!=null&&!temp.getChildren().containsKey(chs[i])){
				temp=temp.getFail();
			}
			temp=temp==null?this.root:temp.getChildren().get(chs[i]);
			
			if(temp!=null){
				TrieNode isEnd = temp;
				while(isEnd!=null){
					if(isEnd.getLength()>0){
						str = replaceKey(str, i-isEnd.getLength()+1, i+1);
						System.out.println(i-isEnd.getLength()+1+"---"+i);
						i=0;
						chs=str.toCharArray();
						len=chs.length;
					}
					isEnd=isEnd.getFail();
				}
			}
			
		}
		
		return str;
	}
	
	
	public void printTrie(TrieNode root){
		Queue<TrieNode> q = new LinkedList<TrieNode>();
		q.add(root);
		
		while(!q.isEmpty()){
			//第一个元素出队
			TrieNode item = q.poll();
			System.out.print(item.getValue());
			//子元素入队
			for(TrieNode child : item.getChildren().values()){
				q.add(child);
			}
			
		}
			
	}
	
	@Test
	public static void test() throws ParseException{
		
		boolean isWeekEnd = false;
		boolean isIgone = false;
		boolean isNeed = false;
		int day;
		
		String[] igone = { "2019年04月05日", "2019年04月06日", "2019年04月07日",
				"2019年05月01日", "2019年05月01日", "2019年05月02日", "2019年05月03日","2019年05月04日"
				,"2019年06月07日","2019年06月08日","2019年06月09日"};
		String[] need = {"2019年04月28日","2019年05月05日"};
		Calendar c = Calendar.getInstance();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
		String str = "";
		String date =  "2019年02月18日";
		//System.out.println(date);
		str+=date+"\r\n";
		while(!date.equals("2019年06月18日")){
			date =  DateUtil.addDay(date, 1,"yyyy年MM月dd日");
			c.setTime(sdf.parse(date));
			day = c.get(c.DAY_OF_WEEK);
			isWeekEnd = day==1||day==7;
			
			isIgone = false;
			for(String item : igone){
				if(item.equals(date))
					isIgone = true;
			}
			isNeed=false;
			for(String item : need){
				if(item.equals(date))
					isNeed = true;
			}
			
			if(isNeed||!isWeekEnd&&!isIgone){
				str+=date+"\r\n";
			}
			
		};
		System.out.println(str);
		
	}
	
	public void randStr(){
		String[] strs  = {"表现良好","表现正常","工作认真","态度端正"};
		String str="";
		for(int i=0;i<84;i++){
			str+=strs[(int)(Math.random()*10)%4]+"\r\n";
			
		}
		System.out.println(str);
	}
	
	
	public static void main(String[] args) throws ParseException {
		String[] strs = {"123","212","134"};
		
		Aho a = new Aho(strs);
		//System.out.println(a.wordPass("12345123"));;
		//test();
		a.randStr();
	}
	
}
